export ROOT = $(shell pwd)/
export CFLAGS = gcc
export CXXFLAGS = g++
export ARCH = $(shell arch)
#export LIBXML2 = /usr/include/libxml2

export INCLUDE = $(ROOT)include/
export LIB = $(ROOT)lib/
export SRC = $(ROOT)src/
export CONF = $(ROOT)conf/

export INOTIFY_SRC = $(SRC)inotify/
export LOGGER_SRC = $(SRC)logger/
export CONFIG_SRC = $(SRC)config/
export SYNCER_SRC = $(SRC)syncer/
export ERROR_SRC = $(SRC)error/
export UTILITY_SRC = $(SRC)utility/


#paras when release
TARGET = $(ROOT)bin/inotify-sync
#paras when debug
DEBUG_TARGET = $(ROOT)bin/debug-inotify-sync
export DEBUG_FLAGS = -g -Wall
#paras when unit test
UT_TARGET = $(ROOT)bin/ut-inotify-sync
export UT_FLAGS = -g -Wall -DUT

#All
.PHONY: all
all: $(TARGET)
$(TARGET): main.o inotify logger config syncer error
	@if [ "$(ARCH)" = "x86_64" ];\
	then \
		ln -sT $(LIB)libxml2_64.a $(LIB)libxml2.a;\
		ln -sT $(LIB)libz_64.a $(LIB)libz.a;\
		ln -sT $(LIB)libpthread_64.a $(LIB)libpthread.a;\
	elif [ "$(ARCH)" = "i686" ];\
	then \
		ln -sT $(LIB)libxml2_32.a $(LIB)libxml2.a;\
		ln -sT $(LIB)libz_32.a $(LIB)libz.a;\
		ln -sT $(LIB)libpthread_32.a $(LIB)libpthread.a;\
	fi
	$(CXX) -o $(TARGET) -static -I$(INOTIFY_SRC) -I$(CONFIG_SRC) \
				-I$(SYNCER_SRC) -I$(ERROR_SRC) -I$(UTILITY_SRC) \
				main.o -L$(LIB) -linotify -llogger -lconfig -lsyncer -lerror -lxml2 -lpthread -lz
main.o: $(SRC)main.cpp
	$(CXX) -c -I$(INOTIFY_SRC) -I$(LOGGER_SRC) -I$(CONFIG_SRC) \
					-I$(SYNCER_SRC)	-I$(ERROR_SRC) \
					-I$(UTILITY_SRC) -I$(INCLUDE) $(SRC)main.cpp
inotify: $(INOTIFY_SRC)Inotify.cpp $(INOTIFY_SRC)Inotify.h $(INOTIFY_SRC)EventHandler.cpp $(INOTIFY_SRC)EventHandler.h
	cd $(INOTIFY_SRC) && make all
logger: $(LOGGER_SRC)Logger.cpp $(LOGGER_SRC)Logger.h
	cd $(LOGGER_SRC) && make all
config: $(CONFIG_SRC)ProfileXml.cpp $(CONFIG_SRC)ProfileXml.h $(CONFIG_SRC)ConfigXml.cpp $(CONFIG_SRC)ConfigXml.h $(CONFIG_SRC)Profile.cpp $(CONFIG_SRC)Profile.h $(CONFIG_SRC)Config.cpp $(CONFIG_SRC)Config.h
	cd $(CONFIG_SRC) && make all
syncer: $(SYNCER_SRC)Syncer.cpp $(SYNCER_SRC)Syncer.h
	cd $(SYNCER_SRC) && make all
error: $(ERROR_SRC)Error.cpp $(ERROR_SRC)Error.h
	cd $(ERROR_SRC) && make all

#Install
.PHONY: install
install:
	@if [ "$(USER)" != "root" ];\
	then \
		echo "Please run 'make install' as root!";\
		exit 1;\
	fi
	@if [ -e /etc/inotify-sync/ ];\
	then \
		rm -rf /etc/inotify-sync;\
	fi
	@cp -R $(CONF) /etc/inotify-sync
	@if [ -e /usr/local/bin/inotify-sync ];\
	then \
		rm -rf /usr/local/bin/inotify-sync;\
	fi
	@cp $(TARGET) /usr/local/bin/inotify-sync
	@if [ -e /var/log/inotify-sync ];\
	then \
		rm -rf /var/log/inotify-sync;\
	fi
	@mkdir /var/log/inotify-sync

#Uninstall
.PHONY: uninstall
uninstall:
	@if [ "$(USER)" != "root" ];\
	then \
		echo "Please run 'make uninstall' as root!";\
		exit 1;\
	fi
	@if [ -e /etc/inotify-sync/ ];\
	then \
		rm -rf /etc/inotify-sync;\
	fi
	@if [ -e /usr/local/bin/inotify-sync ];\
	then \
		rm -rf /usr/local/bin/inotify-sync;\
	fi
	@if [ -e /var/log/inotify-sync ];\
	then \
		rm -rf /var/log/inotify-sync;\
	fi

#Debug
.PHONY: debug
debug: $(DEBUG_TARGET)
$(DEBUG_TARGET): main.o debug_inotify debug_logger debug_config debug_syncer debug_error
	$(CXX) $(DEBUG_FLAGS) -o $(DEBUG_TARGET) -I$(INOTIFY_SRC) \
				-I$(CONFIG_SRC) -I$(SYNCER_SRC) \
				-I$(ERROR_SRC) -I$(UTILITY_SRC) \
				main.o -L$(LIB) -ldebug_inotify -ldebug_logger -ldebug_config -ldebug_syncer -ldebug_error -lpthread -lxml2
debug_main.o: $(SRC)main.cpp
	$(CXX) -c $(DEBUG_FLAGS) -I$(INOTIFY_SRC) -I$(LOGGER_SRC) \
				-I$(CONFIG_SRC) -I$(SYNCER_SRC) \
				-I$(ERROR_SRC) -I$(UTILITY_SRC) -I$(INCLUDE) $(SRC)main.cpp
debug_inotify: $(INOTIFY_SRC)Inotify.cpp $(INOTIFY_SRC)Inotify.h $(INOTIFY_SRC)EventHandler.cpp $(INOTIFY_SRC)EventHandler.h
	cd $(INOTIFY_SRC) && make debug
debug_logger: $(LOGGER_SRC)Logger.cpp $(LOGGER_SRC)Logger.h
	cd $(LOGGER_SRC) && make debug
debug_config: $(CONFIG_SRC)ProfileXml.cpp $(CONFIG_SRC)ProfileXml.h $(CONFIG_SRC)ConfigXml.cpp $(CONFIG_SRC)ConfigXml.h $(CONFIG_SRC)Profile.cpp $(CONFIG_SRC)Profile.h $(CONFIG_SRC)Config.cpp $(CONFIG_SRC)Config.h
	cd $(CONFIG_SRC) && make debug
debug_syncer: $(SYNCER_SRC)Syncer.cpp $(SYNCER_SRC)Syncer.h
	cd $(SYNCER_SRC) && make debug
debug_error: $(ERROR_SRC)Error.cpp $(ERROR_SRC)Error.h
	cd $(ERROR_SRC) && make debug

#Unit Test
.PHONY: ut
ut: $(UT_TARGET)
$(UT_TARGET): ut_main.o ut_inotify ut_logger ut_config ut_syncer
	$(CXX) $(UT_FLAGS) -o $(UT_TARGET) -I$(INOTIFY_SRC) -I$(CONFIG_SRC) -I$(SYNCER_SRC) -I$(ERROR_SRC) -I$(UTILITY_SRC) ut_main.o -L$(LIB) -linotify -llogger -lut_config -lsyncer -lxml2 -lpthread -lcppunit -ldl
ut_main.o: $(SRC)ut_main.cpp $(SRC)main.h ut_inotify ut_logger
	$(CXX) -c $(UT_FLAGS) -I$(INOTIFY_SRC) -I$(LOGGER_SRC) -I$(CONFIG_SRC) -I$(SYNCER_SRC) -I$(ERROR_SRC)) -I$(UTILITY_SRC) -I$(INCLUDE) $(SRC)ut_main.cpp
ut_inotify: $(INOTIFY_SRC)Inotify.cpp $(INOTIFY_SRC)Inotify.h $(INOTIFY_SRC)EventHandler.cpp $(INOTIFY_SRC)EventHandler.h
	cd $(INOTIFY_SRC) && make
ut_logger: $(LOGGER_SRC)Logger.cpp $(LOGGER_SRC)Logger.h
	cd $(LOGGER_SRC) && make
ut_config: $(CONFIG_SRC)Config.cpp $(CONFIG_SRC)Config.h $(CONFIG_SRC)Profile.cpp $(CONFIG_SRC)Profile.h
	cd $(CONFIG_SRC) && make ut
ut_syncer: $(SYNCER_SRC)Syncer.cpp $(SYNCER_SRC)Syncer.h
	cd $(SYNCER_SRC) && make
ut_error: $(ERROR_SRC)Error.cpp $(ERROR_SRC)Error.h
	cd $(ERROR_SRC) && make

#Clean
.PHONY: clean
clean:
	-rm *.o $(TARGET) $(DEBUG_TARGET) $(UT_TARGET)
	cd $(INOTIFY_SRC) && make clean
	cd $(LOGGER_SRC) && make clean
	cd $(CONFIG_SRC) && make clean
	cd $(SYNCER_SRC) && make clean
	cd $(ERROR_SRC) && make clean
